﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EzDesk.Core.Model;
using EzDesk.EzAppApi.Utility.CoreAppService;
using EzDesk.Utility.ServiceReference;


namespace EzDesk.EzAppApi.Utility
{
    // 客户端App使用AppService的帮助类
    // 考虑可以在这个地方实现本地Cache，减少WebService请求次数
    // todo: 解决好Faulted State的问题
    public class EzApiClient : IEzApiClient
    {
        IDictionary<Guid, SimpleUser> simpleUserCache;
        IDictionary<Guid, Dept> deptCache;
        private object _lockObj = new object();

        public static readonly EzApiClient Instance = new EzApiClient();

        ICoreAppService _coreAppService
        {
            get { return ServiceReferenceFactory<ICoreAppService, CoreAppServiceClient>.GetService(); }
        }

        public EzApiClient()
        {
            simpleUserCache = new Dictionary<Guid, SimpleUser>();
        }


        public UserProfile GetUserProfileById(Guid userId)
        {
            return _coreAppService.GetUserProfileById(userId);
        }

        public IList<SimpleUser> GetSimpleUserInfos(string memberstring)
        {
            return _coreAppService.GetSimpleUserInfos(memberstring);
        }

        public IList<Dept> GetAllDepts()
        {
            // 如果超时 否则不刷新
            if (!isCacheAvailable())
            {
                refreshDeptCache();
            }
            return deptCache.Values.ToList();
        }

        public Dept GetDeptById(Guid id)
        {
            if (!isCacheAvailable())
            {
                refreshDeptCache();
            }

            if (deptCache == null || !deptCache.ContainsKey(id))
            {
                refreshDeptCache();
            }
            return deptCache[id];            
        }

        private bool isCacheAvailable()
        {
            return deptCache != null && deptCache.Count > 0;
        }

        private void refreshDeptCache()
        {
            deptCache = new Dictionary<Guid, Dept>();

            var allDept = _coreAppService.GetAllDepts();
            deptCache.Clear();
            foreach (var dept in allDept)
            {
                deptCache.Add(dept.Id, dept);
            }
        }

        public IList<SimpleUser> GetAllUsersByMemberString(string memberString)
        {
            return _coreAppService.GetAllUsersByMemberString(memberString);
        }
        
        public IDictionary<Guid, string> GetChildrenByMemberString(string memberString)
        {
            return _coreAppService.GetChildrenByMemberString(memberString);
        }

        public IList<Group> GetAllSystemGroups()
        {
            return _coreAppService.GetAllSystemGroups();
        } 
        
       
        public void UpdateFeedData(Guid updateFeedId, string newFeedData)
        {
            _coreAppService.UpdateFeedData(updateFeedId, newFeedData);
        }

        public void SetFeedIsAvailable(Guid feedId, string memberString, bool isAvailable)
        {
            _coreAppService.SetFeedIsAvailable(feedId, memberString, isAvailable);
        }

        public SimpleUser GetSimpleUserById(Guid userId)
        {
            if (!simpleUserCache.ContainsKey(userId))
                lock (_lockObj)
                    if (!simpleUserCache.ContainsKey(userId))
                    {
                        SimpleUser user = _coreAppService.GetSimpleUserById(userId);
                        simpleUserCache.Add(userId, user);
                    }

            return simpleUserCache[userId];
        }

        public Group GetGroupById(Guid groupId)
        {
            return _coreAppService.GetGroupById(groupId);
        }

        public IList<Group> GetGroups(string groupIdStrs)
        {
            return _coreAppService.GetGroups(groupIdStrs);
        }

        public void SetFeedsIsAvailable(string feedIdStrs, string memberstring, bool isAvailable)
        {
            _coreAppService.SetFeedsIsAvailable(feedIdStrs, memberstring, isAvailable);
        }
        
        public void UpdateFeedsData(string feedIdsStr, string updateDataStr)
        {
            _coreAppService.UpdateFeedsData(feedIdsStr, updateDataStr);
        }

        public void UpdatePersonalFeedData(Guid feedId, string memberstring, string feedDataEx)
        {
            _coreAppService.UpdatePersonalFeedData(feedId, memberstring, feedDataEx);
        }





        public Group GetGroupByName(string groupName)
        {
            return _coreAppService.GetGroupByName(groupName);
        }

        public Group GetSystemGroup(string sysGroupName)
        {
            return _coreAppService.GetSystemGroup(sysGroupName);
        }




        public bool UserHasPermission(string permissionStr, Guid userId)
        {
            return _coreAppService.UserHasPermission(permissionStr, userId);
        }

        public bool GroupHasPermission(string permissionStr, Guid groupId)
        {
            return _coreAppService.GroupHasPermission(permissionStr, groupId);
        }

        public IList<UserProfile> GetUserProfiles(string memberstring)
        {
            return _coreAppService.GetUserProfiles(memberstring);
        }

        public void UpdateHeadIcon(Guid userId, byte[] iconData, string iconType)
        {
            _coreAppService.UpdateHeadIcon(userId, iconData, iconType);
        }

        public UserHeadImage GetHeadIcon(Guid userId)
        {
            return _coreAppService.GetHeadIcon(userId);
        }


        public void SetFeedRecord(Guid identity, string templateName, string memberstring, Guid feedId, string ignoreUsers)
        {
            _coreAppService.SetFeedRecord(identity, templateName, memberstring, feedId, ignoreUsers);
        }

        public string GetFeedRecord(Guid identity, string templateName, string userId)
        {
            return _coreAppService.GetFeedRecord(identity, templateName, userId);
        }


        public Guid? CreateNewUser(UserProfile newUserProfile, string newPassword)
        {
            return _coreAppService.CreateNewUser(newUserProfile, newPassword);
        }


        public void UpdateUserProfile(UserProfile userProfile)
        {
             _coreAppService.UpdateUserProfile(userProfile);
        }

        public void ChangePassword(Guid userId, string oldPassword, string newPassword)
        {
            _coreAppService.ChangePassword(userId, oldPassword, newPassword);
        }


        public void UpdatePersonalFeedType(Guid feedId, string memberstring, string feedTypeStr)
        {
            _coreAppService.UpdatePersonalFeedType(feedId, memberstring, feedTypeStr);
        }


        public Guid SendFeed(string templateName, string feedData, string memberString, Guid? senderId, string ignoreUsers, bool isAvailable)
        {
            return _coreAppService.SendFeedByName(templateName, feedData, memberString, senderId, ignoreUsers, isAvailable);
        }


        public void SetFeedIsRead(Guid feedId, string memberstring, bool isRead)
        {
            _coreAppService.SetFeedIsRead(feedId, memberstring, isRead);
        }

        public void SetFeedsIsRead(string feedIdStrs, string memberstring, bool isRead)
        {
            _coreAppService.SetFeedsIsRead(feedIdStrs, memberstring, isRead);
        }

        public Organization GetOrganizationInfo()
        {
            return _coreAppService.GetOrganizationInfo();
        }
    }
}
